using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.SharePoint;

namespace SharePoint.DataMapper
{
	public class Caml<T>
		where T : IItemBase
	{
		public static ViewExpression View()
		{
			return new ViewExpression(typeof(IOrderedQueryable<>).MakeGenericType(typeof(T)));
		}

		public static WhereExpression Where(LogicalExpression expression)
		{
			return new WhereExpression(typeof(IOrderedQueryable<>).MakeGenericType(typeof(T)), expression);
		}

		public static OrderByExpression OrderBy(params FieldRefExpression[] fieldRefExpression)
		{
			return new OrderByExpression(typeof(IOrderedQueryable<>).MakeGenericType(typeof(T)), fieldRefExpression);
		}

		public static OrderByExpression OrderBy(IEnumerable<FieldRefExpression> fieldRefExpression)
		{
			return new OrderByExpression(typeof(IOrderedQueryable<>).MakeGenericType(typeof(T)), fieldRefExpression);
		}

		public static FieldRefExpression FieldRef(PropertyInfo info, FieldAttribute attribute)
		{
			string fieldType = attribute.FieldType == SPFieldType.Invalid ? attribute.Type.Name : attribute.FieldType.ToString();
			return new FieldRefExpression(info.PropertyType, attribute.Field, fieldType);
		}

		public static FieldRefExpression FieldRef(PropertyInfo propertyInfo)
		{
			FieldAttribute fieldAttribute = propertyInfo.GetInterfaceAttribute<FieldAttribute>();
			return FieldRef(propertyInfo, fieldAttribute);
		}

		public static FieldRefExpression FieldRef(string propertyName)
		{
			PropertyInfo propertyInfo = (from p in ItemManager<T>.Properties.Keys where p.Name == propertyName select p).FirstOrDefault();
			if (propertyInfo == null)
			{
				throw new ArgumentOutOfRangeException(propertyName, "Property not found!");
			}
			FieldAttribute fieldAttribute = propertyInfo.GetInterfaceAttribute<FieldAttribute>();
			return FieldRef(propertyInfo, fieldAttribute);
		}
	}
}